package com.wangmeng.book.server;

import com.wangmeng.book.server.action.*;
import org.apache.log4j.Logger;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * User: 王猛
 * Date: 13-9-24
 */
public class CommandSession extends Thread {
    private static final Logger logger = Logger.getLogger(CommandSession.class);
    private String sessionIp;
    private Socket client;
    private ObjectInputStream objIn;
    private ObjectOutputStream objOut;
    private AtomicBoolean isLogin = new AtomicBoolean(false);

    public CommandSession(Socket client) {
        this.client = client;
        sessionIp = this.client.getInetAddress().getHostAddress();

    }

    @Override
    public void run() {
        super.run();
        logger.info("会话开始!IP:" + sessionIp);
        try {
            objIn = new ObjectInputStream(client.getInputStream());
            objOut = new ObjectOutputStream(client.getOutputStream());
            Command cmd = null;
            while ((cmd = (Command) objIn.readObject()) != null) {
                CommandResult cr = executeCommand(cmd);
                if (cr != null && objOut != null) {
                    objOut.writeObject(cr);
                    objOut.reset();
                }
                if (!isLogin.get()) {
                    break;
                }
            }
            client.close();
        } catch (Exception ex) {
            logger.error("会话异常,IP:" + sessionIp, ex);
        } finally {
            isLogin.compareAndSet(true, false);
            logger.info("会话结束!IP:" + sessionIp);
        }
    }

    /**
     * 执行命令
     *
     * @param cmd 命令信息
     * @return 执行结果信息
     */
    private CommandResult executeCommand(Command cmd) {
        logger.info("IP:" + sessionIp + ",开始执行命令:" + cmd.getCmdCode() + ",DATA:" + cmd.getData());
        try {
            int cCode = cmd.getCmdCode();
            if (cCode == Command.CMD_LOGIN) {
                //登陆名称执行登陆验证
                LoginAction la = new LoginAction();
                CommandResult cr = la.execute(cmd);
                if (cr.getCode() == CommandResult.CODE_SUCCESS) {
                    isLogin.set(true);
                }
                return cr;
            } else if (isLogin.get()) {
                //如果不是登陆命令检查是否登陆成功
                switch (cCode) {
                    case Command.CMD_LOGOUT: {
                        isLogin.compareAndSet(true, false);
                        CommandResult cr = new CommandResult();
                        cr.setCode(CommandResult.CODE_SUCCESS);
                        return cr;
                    }
                    case Command.CMD_BOOK_LIST: {
                        BookListAction bla = new BookListAction();
                        return bla.execute(cmd);
                    }
                    case Command.CMD_LIST_PARTITION: {
                        PartitionListAction pla = new PartitionListAction();
                        return pla.execute(cmd);
                    }
                    case Command.CMD_BOOK_REJECT:
                    case Command.CMD_BOOK_RECEIVE: {
                        BookFirstDealAction bfdAction = new BookFirstDealAction();
                        return bfdAction.execute(cmd);
                    }
                    case Command.CMD_BOOK_PUBLISH: {
                        BookPublishAction bpa = new BookPublishAction();
                        return bpa.execute(cmd);
                    }
                    case Command.CMD_JOB_START:
                    case Command.CMD_JOB_STOP:
                    case Command.CMD_JOB_SHUTDOWN: {
                        JobManageAction jma = new JobManageAction();
                        return jma.execute(cmd);
                    }
                }
            }
        } catch (Exception ex) {
            logger.info("IP:" + sessionIp + ",执行命令异常:" + cmd.getCmdCode(), ex);
        } finally {
            logger.info("IP:" + sessionIp + ",执行命令结束:" + cmd.getCmdCode());
        }
        return null;
    }
}
